﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI.WebControls;
using WebGrease.Css.Extensions;
using RechercheEmplois.Utilities;

namespace RechercheEmplois.Models
{
    public enum OffreType
    {
        TempsPartiel, TempPlein, Intern, Stage, JobSaisonnier, JobEtudiant
    }
    
    public class Offre
    {
        public int ID { get; set; }

        [Required]
        [Display(Name = "Job Title")]
        public string Libelle { get; set; }

        [Display(Name = "Niveau Etude")]
        public string NiveauEtude { get; set; }

        [Required]
        [Display(Name = "Description")]
        public string Description { get; set; }

        [Required]
        [Display(Name = "Horaire de travail")]
        public string HoraireTravail { get; set; }

        [Display(Name = "Rémunération")]
        public long? RenumHoraire { get; set; }

        [Display(Name = "Début du contract")]
        public DateTime? DebutContrat { get; set; }

        [Display(Name = "Fin du contract")]
        public DateTime? FinContrat { get; set; }

        [Display(Name = "Experiences minimal")]
        public int? ExpMin { get; set; }

        public string Commentaire { get; set; }

        public DateTime DateCreated { get; set; }

        [Required]
        [Display(Name = "Job Type")]
        public OffreType Type { get; set; }

        //Forgein Keys
        [Required]
        public int DomaineID { get; set; }

        [Required]
        public int VilleID { get; set; }

        public int Valide { get; set; }

        //La personne qui a depose cette offre
        [Required]
        public int UtilisateurID { get; set; }

        //Navigation Properties
        public virtual ICollection<MotCle> MotCles { get; set; }

        public virtual Domaine Domaine { get; set; }

        public virtual Ville Ville { get; set; }

        public virtual Utilisateur Recruiteur { get; set; }

        public virtual ICollection<Sauvegarde> Sauvegardes { get; set; }

        public virtual ICollection<Postule> Postules { get; set; }

        //Extends property
        [NotMapped]
        [Display(Name = "Les mots cles (separés par les virgules)")]
        public string TagWords { get; set; }

        [NotMapped]
        public double Probability { get; set; }

        public override string ToString()
        {
            return Libelle + " (" + Probability + ")";
        }

        //La methode trouve la probabilite de ce offre qui corresponde aux criteres recherchees
        public double Probabilite(string searchKeys, string[] selectedProvines, string[] selectedTypes, string[] selectedSecteurs, string[] selectedNiveauEtudes, int remuValue)
        {
            var prob = 0.0d;
            //Rechercher par mot clefs
            if (!string.IsNullOrEmpty(searchKeys))
            {
                string[] keys = searchKeys.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                //Rechercher par les titres
                int count = 0;
                MotCles.ForEach(m =>
                {
                    keys.ForEach(k =>
                    {
                        if (m.Libelle.ToLower().Contains(k.ToLower()))
                        {
                            count++;
                        }
                    });
                });
                if (count == 0)
                {
                    //Caculer sur le desciption de l'offre
                    //Concac tous les mots possible a partir de keys
                    for (int i = keys.Length; i > 0 && count == 0; i--)
                    {
                        for (int j = 0; j <= keys.Length - i; j++)
                        {
                            string joined = string.Join(" ", keys, j, i);
                            if (Description.ToLower().Contains(joined.ToLower()))
                            {
                                count = i;
                                break;
                            }
                        }
                    }
                    if (count == 0)
                    {
                        prob = -1.0f;
                        goto ret;
                    }
                }
                prob += (float)count / keys.Length * 0.2f;
            }
            else{
                prob += 0.2f;
            }

            if (selectedProvines != null)
            {
                if (selectedProvines.Contains(Ville.Provine.ID.ToString())){
                    prob += 0.15f;
                }
                else{
                    prob = -1.0f;
                    goto ret;
                }
            }else{ 
                prob += 0.15f; 
            }

            if (selectedTypes != null)
            {
                if (selectedTypes.Contains(Type.ToString()))
                {
                    prob += 0.15f;
                }
                else{
                    prob = -1.0f;
                    goto ret;
                }
            }else{
                prob += 0.15f;
            }

            if (selectedSecteurs != null)
            {
                if (selectedSecteurs.Contains(Domaine.ID.ToString()))
                {
                    prob += 0.15f;
                }
                else
                {
                    prob = -1.0f;
                    goto ret;
                }
            }else
            {
                prob += 0.15f;
            }

            if (selectedNiveauEtudes != null)
            {
                string nesSelected = string.Join(",", selectedNiveauEtudes);
                prob += ExtendUtilities.CalculateSimilarity(NiveauEtude, nesSelected) * 0.15f;
            }
            else
            {
                prob += 0.15f;
            }

            if (remuValue == 0 || RenumHoraire == null)
            {
                prob += 0.2f;
            }
            else
            {
                if (remuValue > RenumHoraire)
                {
                    prob = -1.0f;
                    goto ret;
                }
                else
                {
                    prob += (1.0 + (double)((remuValue - RenumHoraire) / RenumHoraire)) * 0.2f;
                }
            }
            ret: Probability = prob;
            return prob;
        }
    }
}